package algorithm;

import DataStructure.Tree;
import org.junit.Test;
import util.IOUtil;

import java.awt.*;
import java.io.*;
import java.math.BigInteger;
import java.util.Random;

public class Serialize {

    @Test
    public void MkSerializeTest(){
        CPABESetUp setup=new CPABESetUp();
        setup.sysInitiate();
        CPABEMK mk=setup.getMasterKey();
        String[] masterKey=mk.toStringArray();
        for(String data: masterKey){
            System.out.println(data);
        }
    }

    @Test
    public void MKDeserializeTest(){
        CPABESetUp setup=new CPABESetUp();
        setup.sysInitiate();
        CPABEMK mk=setup.getMasterKey();
        String[] temp=mk.toStringArray();
        CPABEMK mk2=new CPABEMK();
        mk2.fromStringArray(temp,setup.getPairing());
    }

    @Test
    public void PKSerializeTest(){
        CPABESetUp setup=new CPABESetUp();
        setup.sysInitiate();
        CPABEPK pk=setup.getPubKey();
        String[] array=pk.toStringArray();
        for (String data:array){
            System.out.println(data);
        }
    }

    @Test
    public void PkDeserializeTest() throws IOException {
        CPABESetUp setup=new CPABESetUp();
        setup.sysInitiate();
        CPABEPK pk=setup.getPubKey();
        long startTime1=System.currentTimeMillis();
        String[] array=pk.toStringArray();
        BufferedWriter out=new BufferedWriter(new FileWriter("pubkey.txt"));
        for (int i = 0; i < array.length; i++) {
                out.write(array[i]);
                out.write("\n");
        }
        out.close();
        long endTime1=System.currentTimeMillis();
        System.out.println(endTime1-startTime1);
        CPABEPK pk2=new CPABEPK();
        long startTime2=System.currentTimeMillis();
        BufferedReader in=new BufferedReader(new FileReader("pubkey.txt"));
        String[] array2=new String[5];
        for (int i = 0; i < array2.length; i++) {
            array2[i]=in.readLine();
        }
        in.close();
        pk2.fromStringArray(array2,setup.getPairing());
        long endTime2= System.currentTimeMillis();
        System.out.println(endTime2-startTime2);
    }

    @Test
    public void unionSerializeTest(){
        CPABESetUp setup=new CPABESetUp();
        setup.sysInitiate();
        CPABEKeyGen keyGen=new CPABEKeyGen(setup.getG(),setup.getPairing());
        CPABEAttKey attKey=keyGen.generateAttributeKey("1,2,3",setup.getMasterKey());
        String sUnion1=attKey.getDj1()[0].toString();
        System.out.println(sUnion1);
    }

    @Test
    public void unionDeserializeTest(){
        CPABESetUp setup=new CPABESetUp();
        setup.sysInitiate();
        CPABEKeyGen keyGen=new CPABEKeyGen(setup.getG(),setup.getPairing());
        CPABEAttKey attKey=keyGen.generateAttributeKey("1,2,3",setup.getMasterKey());
        EAUnion union=attKey.getDj1()[0];
        String sUnion1=union.toString();
        System.out.println(sUnion1);
        EAUnion union2=new EAUnion();
        union2.fromString(sUnion1, setup.getPairing().getG1());
    }

    @Test
    public void attKeySerializeTest(){
        CPABESetUp setup=new CPABESetUp();
        setup.sysInitiate();
        CPABEKeyGen keyGen=new CPABEKeyGen(setup.getG(),setup.getPairing());
        CPABEAttKey attKey=keyGen.generateAttributeKey("1,2,3",setup.getMasterKey());
        long startTime=System.currentTimeMillis();
        String[] arrayAttKey=attKey.toStringArray();
        long endTime=System.currentTimeMillis();
        System.out.println(endTime-startTime);
        for(String data:arrayAttKey){
            System.out.println(data);
        }
    }

    @Test
    public void attKeyDeserializeTest(){
        CPABESetUp setup=new CPABESetUp();
        setup.sysInitiate();
        CPABEKeyGen keyGen=new CPABEKeyGen(setup.getG(),setup.getPairing());
        CPABEAttKey attKey=keyGen.generateAttributeKey("1,2,3",setup.getMasterKey());

        String[] arrayAttKey=attKey.toStringArray();

        CPABEAttKey attKey2=new CPABEAttKey();
        attKey2.fromStringArray(arrayAttKey,setup.getPairing());
    }

    @Test
    public void ctSerializeTest() throws Exception {
        CPABESetUp setup=new CPABESetUp();
        setup.sysInitiate();
        CPABEenc enc=new CPABEenc(setup.getPairing(),setup.getPubKey(), setup.getOrder());
        CPABECT ct=enc.encrypt(new BigInteger("123").toString(),"1#2");
        String[] arrayCT=ct.toStringArray();
        for (int i = 0; i < arrayCT.length; i++) {
            System.out.println(arrayCT[i]);
        }
    }

    @Test
    public void ctDeserializeTest() throws Exception {
        CPABESetUp setup=new CPABESetUp();
        setup.sysInitiate();
        CPABEenc enc=new CPABEenc(setup.getPairing(),setup.getPubKey(), setup.getOrder());
        CPABECT ct=enc.encrypt(new BigInteger("123").toString(),"1#2");
        String[] arrayCT=ct.toStringArray();
        CPABECT ct2=new CPABECT();
        ct2.fromStringArray(arrayCT,setup.getPairing());
    }

    @Test
    public void treeSerializeTest() throws Exception {
        CPABESetUp setup=new CPABESetUp();
        setup.sysInitiate();
        CPABEenc enc=new CPABEenc(setup.getPairing(),setup.getPubKey(), setup.getOrder());
        CPABECT ct=enc.encrypt(new BigInteger("123").toString(),"1#2");
        Tree tree=ct.getTree();
        String[] arrayTree=tree.toStringArray();
    }

    /**
     * 展示全流程包含文件读写的序列化与反序列化
     * @throws Exception
     */
    @Test
    public void totalTest() throws Exception {
        long startTime=System.currentTimeMillis();
        Random random=new Random();
        CPABESetUp setup=new CPABESetUp();
        setup.sysInitiate();
        //公钥的序列化与反序列化
        IOUtil.writeFile("pk.txt",setup.getPubKey().toStringArray());
        CPABEPK pk=new CPABEPK();
        pk.fromStringArray(IOUtil.readPk("pk.txt"),setup.getPairing());
        //主密钥的序列化与反序列化
        IOUtil.writeFile("mk.txt",setup.getMasterKey().toStringArray());
        CPABEMK mk=new CPABEMK();
        mk.fromStringArray(IOUtil.readMK("mk.txt"), setup.getPairing());
        CPABEenc enc=new CPABEenc(setup.getPairing(),pk, setup.getOrder());
        BigInteger plaintext=new BigInteger(256,random);
        System.out.println("原文为："+plaintext);
        //密文的序列化与反序列化
        IOUtil.writeFile("ct.txt",enc.encrypt(plaintext.toString(),"a#b").toStringArray());
        CPABECT ct=new CPABECT();
        ct.fromStringArray(IOUtil.readCT("ct.txt"),setup.getPairing());
        //属性密钥的序列化与反序列化
        CPABEKeyGen keyGen=new CPABEKeyGen(setup.getG(),setup.getPairing());
        IOUtil.writeFile("attributeKey.txt",keyGen.generateAttributeKey("a,b",setup.getMasterKey()).toStringArray());
        CPABEAttKey attkey=new CPABEAttKey();
        attkey.fromStringArray(IOUtil.readAttKey("attributeKey.txt"),setup.getPairing());
        CPABEdec dec=new CPABEdec();
        String recoverText=dec.decrypt(ct,attkey);
        System.out.println("明文为:"+recoverText);
        long endTime=System.currentTimeMillis();
        System.out.println(endTime-startTime);
    }

}
